#include "stdafx.h"
#include "IMultInterface2.h"
#include "RealIBase.h"

RealIBase::RealIBase()
{
}

RealIBase::~RealIBase()
{
}

HRESULT STDMETHODCALLTYPE RealIBase::QueryInterface(REFIID riid, void **ppv)
{
    if (IsEqualIID(riid, IID_IUnknown) ||
        IsEqualIID(riid, IID_IMultInterface) ||
        IsEqualIID(riid, IID_IBase))
    {
        *ppv = this;
        AddRef();
        return S_OK;
    }
    else if (IsEqualIID(riid, IID_ISub1))
    {
        *ppv = (char *)this + offsetof(IMultInterface, sub1);
        AddRef();
        return S_OK;
    }
    else if (IsEqualIID(riid, IID_ISub2))
    {
        IMultInterface *pMultInterface = (IMultInterface *)this;
        if (pMultInterface->sub2 == NULL)
        {
            pMultInterface->sub2 = new RealISub2(this);
            if (pMultInterface->sub2 == NULL)
            {
                *ppv = NULL;
                return E_OUTOFMEMORY;
            }
        }
        *ppv = pMultInterface->sub2;
        AddRef();
        return S_OK;
    }
    else
    {
        *ppv = NULL;
        return E_NOINTERFACE;
    }
}

ULONG STDMETHODCALLTYPE RealIBase::AddRef()
{
    IMultInterface *pMultInterface = (IMultInterface *)this;
    return ++pMultInterface->count;
}

ULONG STDMETHODCALLTYPE RealIBase::Release()
{
    IMultInterface *pMultInterface = (IMultInterface *)this;
    if (--pMultInterface->count == 0)
    {
        delete pMultInterface;
        InterlockedDecrement(&OutstandingObjects);
        return 0;
    }
    return pMultInterface->count;
}

HRESULT STDMETHODCALLTYPE RealIBase::Sum(LONG x, LONG y, LONG *r)
{
    if (r == NULL) return E_POINTER;
    *r = x + y;
    return S_OK;
}
